package algocity.modelo.catastrofe;

import algocity.modelo.azar.FuncionAzar;
import algocity.modelo.juego.Cambiador;
import algocity.modelo.mapa.*;
import algocity.modelo.zona.Ruptura;

public abstract class Godzilla
        extends CatastrofeAbstracta {

    protected final FuncionAzar azar;
    protected Mapa mapa;
    protected Hectarea origenEnMapa;

    public Godzilla(Mapa m, FuncionAzar azar) {
        this.mapa = m;
        this.azar = azar;
    }

    public void hacerDanio() {
        origenEnMapa = mapa.hectareaDeBordeAlAzar();
        Cambiador<Iterador2DDireccion> direccion = calcularCaminoDeDirecciones();
        seguirElCamino(direccion);
    }

    private void seguirElCamino(Cambiador<Iterador2DDireccion> direccion) {
        try {
            Iterador2D<Hectarea> iterator = mapa.iterator(origenEnMapa.getPosicion());

            Hectarea hectarea = iterator.elementoActual();
            new RompedorDeHectarea(this, llamador).operar(hectarea);

            while (iterator.hayMasHacia(direccion.item())) {
                iterator.moverHacia(direccion.item());
                hectarea = iterator.elementoActual();
                new RompedorDeHectarea(this, llamador).operar(hectarea);
                direccion.cambiar();
            }
        } catch (FueraDelMapaException e) {
            // Fin del camino
        }
    }

    protected abstract Cambiador<Iterador2DDireccion> calcularCaminoDeDirecciones();

    @Override
    public float getDanioSegunConstruccion(Ruptura rompible) {
        return rompible.getDanioGodzilla();
    }

    @Override
	public boolean esTerremoto() {
		return false;
	}

    @Override
	public boolean esGodzilla() {
		return true;
	}

    public String toString() {
        return "Godzilla";
    }

    protected Iterador2DDireccion calcularOpuesta(Iterador2DDireccion direccion) {

        // FIXME cambiar algoritmo !!
        switch (direccion) {
            case IZQUIERDA:
                return Iterador2DDireccion.DERECHA;

            case DERECHA:
                return Iterador2DDireccion.IZQUIERDA;

            case ARRIBA:
                return Iterador2DDireccion.ABAJO;

            case ABAJO:
                return Iterador2DDireccion.ARRIBA;

        }

        return null;

    }
}
